Introduction

Aiming to show a complete workthrough of 10X Spatial Gene Expression data from raw reads to analysis and visualization using 10X genomics spaceranger and Seurat.

Acknowledgements

Tutorial adapted from 10X spaceranger tutorial and Seurat vignette

Data

The data is publicly available Mouse Brain Coronal Section

https://www.10xgenomics.com/resources/datasets/mouse-brain-section-coronal-1-standard-1-1-0

curl https://s3-us-west-2.amazonaws.com/10x.files/samples/spatial-exp/1.1.0/V1_Adult_Mouse_Brain/V1_Adult_Mouse_Brain_fastqs.tar -o datasets/V1_Adult_Mouse_Brain_fastqs.tar
curl https://cf.10xgenomics.com/samples/spatial-exp/1.1.0/V1_Adult_Mouse_Brain/V1_Adult_Mouse_Brain_image.tif -o datasets/V1_Adult_Mouse_Brain_image.tif

# Download mouse reference
curl -O https://cf.10xgenomics.com/supp/spatial-exp/refdata-gex-mm10-2020-A.tar.gz

Space ranger was used with the following params:

./spaceranger-2.0.0/spaceranger count --id="V1_Adult_Mouse_Brain" \
                   --description="Adult Mouse Brain (Coronal)" \
                   --transcriptome=refdata-gex-mm10-2020-A \
                   --fastqs=datasets/V1_Adult_Mouse_Brain_fastqs \
                   --image=datasets/V1_Adult_Mouse_Brain_image.tif \
                   --slide=V19L01-041 \
                   --area=C1 \
                       --jobmode=local \
                   --localcores=8 \
                       --localmem=40

Load libraries

library(Seurat)
library(ggplot2)
library(patchwork)
library(dplyr)

We are loading in the data directly from the output of spaceranger

Make sure hd5f libraries are installed

#brain <- 
brain <- Load10X_Spatial(data.dir ="outs")

Data preprocessing

plot1 <- VlnPlot(brain, features = "nCount_Spatial", pt.size = 0.1) + NoLegend()
plot2 <- SpatialFeaturePlot(brain, features = "nCount_Spatial") + theme(legend.position = "right")
wrap_plots(plot1, plot2)

The plots show quite a wide variance in molecular counts. This is due to technical variation but also due to natural variation in tissue types across the section. For this reason LogNormalise() is not suitable and Seurat reccomend rthe use of SCTransform() instead

brain <- SCTransform(brain, assay = "Spatial", verbose = FALSE)

Visualisation

Highlight particular features

SpatialFeaturePlot(brain, features = c("Hpca", "Ttr"))

p1 <- SpatialFeaturePlot(brain, features = "Ttr", pt.size.factor = 1)
p2 <- SpatialFeaturePlot(brain, features = "Ttr", alpha = c(0.1, 1))
p1 + p2

Dimensionality reduction, clustering, and visualization

brain <- RunPCA(brain, assay = "SCT", verbose = FALSE)
brain <- FindNeighbors(brain, reduction = "pca", dims = 1:30)
brain <- FindClusters(brain, verbose = FALSE)
brain <- RunUMAP(brain, reduction = "pca", dims = 1:30)
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
p1 <- DimPlot(brain, reduction = "umap", label = TRUE)
p2 <- SpatialDimPlot(brain, label = TRUE, label.size = 3)
p1 + p2

SpatialDimPlot(brain, cells.highlight = CellsByIdentities(object = brain, idents = c(2, 1, 4, 3,
    5, 8)), facet.highlight = TRUE, ncol = 3)

Interactive plots

SpatialDimPlot(brain, interactive = TRUE) 

SpatialFeaturePlot(brain, features = "Ttr", interactive = TRUE)

Identification of spatially variable features

1st method : Using prior knowledge

de_markers <- FindMarkers(brain, ident.1 = 5, ident.2 = 6)

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~04s          
  |+                                                 | 2 % ~04s          
  |++                                                | 3 % ~04s          
  |++                                                | 4 % ~04s          
  |+++                                               | 5 % ~04s          
  |+++                                               | 6 % ~04s          
  |++++                                              | 7 % ~04s          
  |++++                                              | 8 % ~04s          
  |+++++                                             | 9 % ~04s          
  |+++++                                             | 10% ~04s          
  |++++++                                            | 11% ~04s          
  |++++++                                            | 12% ~04s          
  |+++++++                                           | 13% ~04s          
  |+++++++                                           | 14% ~04s          
  |++++++++                                          | 15% ~04s          
  |++++++++                                          | 16% ~04s          
  |+++++++++                                         | 17% ~04s          
  |+++++++++                                         | 18% ~04s          
  |++++++++++                                        | 19% ~04s          
  |++++++++++                                        | 20% ~04s          
  |+++++++++++                                       | 21% ~04s          
  |+++++++++++                                       | 22% ~04s          
  |++++++++++++                                      | 23% ~04s          
  |++++++++++++                                      | 24% ~04s          
  |+++++++++++++                                     | 25% ~04s          
  |+++++++++++++                                     | 26% ~04s          
  |++++++++++++++                                    | 27% ~04s          
  |++++++++++++++                                    | 28% ~04s          
  |+++++++++++++++                                   | 29% ~04s          
  |+++++++++++++++                                   | 30% ~04s          
  |++++++++++++++++                                  | 31% ~03s          
  |++++++++++++++++                                  | 32% ~03s          
  |+++++++++++++++++                                 | 33% ~03s          
  |+++++++++++++++++                                 | 34% ~03s          
  |++++++++++++++++++                                | 35% ~03s          
  |++++++++++++++++++                                | 36% ~03s          
  |+++++++++++++++++++                               | 37% ~03s          
  |+++++++++++++++++++                               | 38% ~03s          
  |++++++++++++++++++++                              | 39% ~03s          
  |++++++++++++++++++++                              | 40% ~03s          
  |+++++++++++++++++++++                             | 41% ~03s          
  |+++++++++++++++++++++                             | 42% ~03s          
  |++++++++++++++++++++++                            | 43% ~03s          
  |++++++++++++++++++++++                            | 44% ~03s          
  |+++++++++++++++++++++++                           | 45% ~03s          
  |+++++++++++++++++++++++                           | 46% ~03s          
  |++++++++++++++++++++++++                          | 47% ~03s          
  |++++++++++++++++++++++++                          | 48% ~03s          
  |+++++++++++++++++++++++++                         | 49% ~03s          
  |+++++++++++++++++++++++++                         | 50% ~02s          
  |++++++++++++++++++++++++++                        | 51% ~02s          
  |++++++++++++++++++++++++++                        | 52% ~02s          
  |+++++++++++++++++++++++++++                       | 53% ~02s          
  |+++++++++++++++++++++++++++                       | 54% ~02s          
  |++++++++++++++++++++++++++++                      | 55% ~02s          
  |++++++++++++++++++++++++++++                      | 56% ~02s          
  |+++++++++++++++++++++++++++++                     | 57% ~02s          
  |+++++++++++++++++++++++++++++                     | 58% ~02s          
  |++++++++++++++++++++++++++++++                    | 59% ~02s          
  |++++++++++++++++++++++++++++++                    | 60% ~02s          
  |+++++++++++++++++++++++++++++++                   | 61% ~02s          
  |+++++++++++++++++++++++++++++++                   | 62% ~02s          
  |++++++++++++++++++++++++++++++++                  | 63% ~02s          
  |++++++++++++++++++++++++++++++++                  | 64% ~02s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~02s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~02s          
  |++++++++++++++++++++++++++++++++++                | 67% ~02s          
  |++++++++++++++++++++++++++++++++++                | 68% ~02s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~01s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~01s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~01s          
  |++++++++++++++++++++++++++++++++++++              | 72% ~01s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~01s          
  |+++++++++++++++++++++++++++++++++++++             | 74% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=05s  
SpatialFeaturePlot(object = brain, features = rownames(de_markers)[1:3], alpha = c(0.1, 1), ncol = 3)

2nd method: Looking for patterns in the data

brain <- FindSpatiallyVariableFeatures(brain, assay = "SCT", features = VariableFeatures(brain)[1:500],
    selection.method = "markvariogram")

More tutorials on data integration, subsetting and multiple slice data available at https://satijalab.org/seurat/articles/spatial_vignette.html

LS0tCnRpdGxlOiAiU3BhdGlhbCB0cmFuc2NyaXB0b21pY3MgaW4gc3BhY2VyYW5nZXIgYW5kIFNldXJhdCB3b3JrZmxvdyIKb3V0cHV0OiBodG1sX25vdGVib29rCmF1dGhvcjogIkVtaWx5IENoYW1iZXJzIgpkYXRlOiAiTGFzdCBjb21waWxlZCBvbiBgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCLCAlWScpYCIKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAogIHRpZHkgPSBUUlVFLAogIHRpZHkub3B0cyA9IGxpc3Qod2lkdGguY3V0b2ZmID0gOTUpLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgZmlnLndpZHRoID0gMTAsCiAgdGltZV9pdCA9IFRSVUUKKQoKYGBgCiMgSW50cm9kdWN0aW9uCgpBaW1pbmcgdG8gc2hvdyBhIGNvbXBsZXRlIHdvcmt0aHJvdWdoIG9mIDEwWCBTcGF0aWFsIEdlbmUgRXhwcmVzc2lvbiBkYXRhIGZyb20gcmF3IHJlYWRzIHRvIGFuYWx5c2lzIGFuZCB2aXN1YWxpemF0aW9uIHVzaW5nIDEwWCBnZW5vbWljcyBzcGFjZXJhbmdlciBhbmQgU2V1cmF0LgoKIyBBY2tub3dsZWRnZW1lbnRzCgpUdXRvcmlhbCBhZGFwdGVkIGZyb20gMTBYIHNwYWNlcmFuZ2VyIHR1dG9yaWFsIGFuZCBTZXVyYXQgdmlnbmV0dGUKCi0gICA8aHR0cHM6Ly9naXRodWIuY29tL3NhdGlqYWxhYi9zZXVyYXQvYmxvYi9tYXN0ZXIvdmlnbmV0dGVzL3NwYXRpYWxfdmlnbmV0dGUuUm1kPgotICAgPGh0dHBzOi8vc3VwcG9ydC4xMHhnZW5vbWljcy5jb20vc3BhdGlhbC1nZW5lLWV4cHJlc3Npb24vc29mdHdhcmUvcGlwZWxpbmVzL2xhdGVzdC90dXRvcmlhbHMvY291bnQtZmYtdHV0b3JpYWw+CgojIERhdGEKClRoZSBkYXRhIGlzIHB1YmxpY2x5IGF2YWlsYWJsZSBNb3VzZSBCcmFpbiBDb3JvbmFsIFNlY3Rpb24KCi0gICBUaXNzdWUgc2VjdGlvbiBvZiAxMCDCtW0gdGhpY2tuZXNzCi0gICBIJkUgaW1hZ2UgYWNxdWlyZWQgdXNpbmcgYSBOaWtvbiBUaTItRSBtaWNyb3Njb3BlCi0gICBTZXF1ZW5jaW5nIERlcHRoOiAxMTUsNTY5IHJlYWQgcGFpcnMgcGVyIHNwb3QKLSAgIFNlcXVlbmNpbmcgQ292ZXJhZ2U6IFJlYWQgMSAtIDI4IGJwIChpbmNsdWRlcyAxNiBicCBTcGF0aWFsIEJhcmNvZGUsIDEyIGJwIFVNSSk7IFJlYWQgMiAtIDEyMCBicCAodHJhbnNjcmlwdCk7IGk3IHNhbXBsZSBpbmRleCAtIDEwIGJwOyBpNSBzYW1wbGUgaW5kZXggLSAxMCBicAotICAgVmlzaXVtIFNsaWRlOiBWMTlMMDEtMDQxCi0gICBDYXB0dXJlIEFyZWE6IEMxCgo8aHR0cHM6Ly93d3cuMTB4Z2Vub21pY3MuY29tL3Jlc291cmNlcy9kYXRhc2V0cy9tb3VzZS1icmFpbi1zZWN0aW9uLWNvcm9uYWwtMS1zdGFuZGFyZC0xLTEtMD4KCmBgYHtiYXNoLCBldmFsICA9RkFMU0V9CmN1cmwgaHR0cHM6Ly9zMy11cy13ZXN0LTIuYW1hem9uYXdzLmNvbS8xMHguZmlsZXMvc2FtcGxlcy9zcGF0aWFsLWV4cC8xLjEuMC9WMV9BZHVsdF9Nb3VzZV9CcmFpbi9WMV9BZHVsdF9Nb3VzZV9CcmFpbl9mYXN0cXMudGFyIC1vIGRhdGFzZXRzL1YxX0FkdWx0X01vdXNlX0JyYWluX2Zhc3Rxcy50YXIKY3VybCBodHRwczovL2NmLjEweGdlbm9taWNzLmNvbS9zYW1wbGVzL3NwYXRpYWwtZXhwLzEuMS4wL1YxX0FkdWx0X01vdXNlX0JyYWluL1YxX0FkdWx0X01vdXNlX0JyYWluX2ltYWdlLnRpZiAtbyBkYXRhc2V0cy9WMV9BZHVsdF9Nb3VzZV9CcmFpbl9pbWFnZS50aWYKCiMgRG93bmxvYWQgbW91c2UgcmVmZXJlbmNlCmN1cmwgLU8gaHR0cHM6Ly9jZi4xMHhnZW5vbWljcy5jb20vc3VwcC9zcGF0aWFsLWV4cC9yZWZkYXRhLWdleC1tbTEwLTIwMjAtQS50YXIuZ3oKCmBgYAoKU3BhY2UgcmFuZ2VyIHdhcyB1c2VkIHdpdGggdGhlIGZvbGxvd2luZyBwYXJhbXM6CgpgYGB7YmFzaCwgZXZhbCAgPUZBTFNFfQouL3NwYWNlcmFuZ2VyLTIuMC4wL3NwYWNlcmFuZ2VyIGNvdW50IC0taWQ9IlYxX0FkdWx0X01vdXNlX0JyYWluIiBcCiAgICAgICAgICAgICAgICAgICAtLWRlc2NyaXB0aW9uPSJBZHVsdCBNb3VzZSBCcmFpbiAoQ29yb25hbCkiIFwKICAgICAgICAgICAgICAgICAgIC0tdHJhbnNjcmlwdG9tZT1yZWZkYXRhLWdleC1tbTEwLTIwMjAtQSBcCiAgICAgICAgICAgICAgICAgICAtLWZhc3Rxcz1kYXRhc2V0cy9WMV9BZHVsdF9Nb3VzZV9CcmFpbl9mYXN0cXMgXAogICAgICAgICAgICAgICAgICAgLS1pbWFnZT1kYXRhc2V0cy9WMV9BZHVsdF9Nb3VzZV9CcmFpbl9pbWFnZS50aWYgXAogICAgICAgICAgICAgICAgICAgLS1zbGlkZT1WMTlMMDEtMDQxIFwKICAgICAgICAgICAgICAgICAgIC0tYXJlYT1DMSBcCgkJICAgICAgICAgICAgICAgLS1qb2Jtb2RlPWxvY2FsIFwKICAgICAgICAgICAgICAgICAgIC0tbG9jYWxjb3Jlcz04IFwKCQkgICAgICAgICAgICAgICAtLWxvY2FsbWVtPTQwCgkJICAgICAgICAgICAgICAgCmBgYAoKIyBMb2FkIGxpYnJhcmllcwoKYGBge3IsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KGRwbHlyKQpgYGAKCldlIGFyZSBsb2FkaW5nIGluIHRoZSBkYXRhIGRpcmVjdGx5IGZyb20gdGhlIG91dHB1dCBvZiBzcGFjZXJhbmdlcgoKTWFrZSBzdXJlIGhkNWYgbGlicmFyaWVzIGFyZSBpbnN0YWxsZWQKCmBgYHtyfQojYnJhaW4gPC0gCmJyYWluIDwtIExvYWQxMFhfU3BhdGlhbChkYXRhLmRpciA9Im91dHMiKQoKCgpgYGAKCiMgRGF0YSBwcmVwcm9jZXNzaW5nCgpgYGB7cn0KcGxvdDEgPC0gVmxuUGxvdChicmFpbiwgZmVhdHVyZXMgPSAibkNvdW50X1NwYXRpYWwiLCBwdC5zaXplID0gMC4xKSArIE5vTGVnZW5kKCkKcGxvdDIgPC0gU3BhdGlhbEZlYXR1cmVQbG90KGJyYWluLCBmZWF0dXJlcyA9ICJuQ291bnRfU3BhdGlhbCIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKd3JhcF9wbG90cyhwbG90MSwgcGxvdDIpCgpgYGAKVGhlIHBsb3RzIHNob3cgcXVpdGUgYSB3aWRlIHZhcmlhbmNlIGluIG1vbGVjdWxhciBjb3VudHMuIFRoaXMgaXMgZHVlIHRvIHRlY2huaWNhbCB2YXJpYXRpb24gYnV0IGFsc28gZHVlIHRvIG5hdHVyYWwgdmFyaWF0aW9uIGluIHRpc3N1ZSB0eXBlcyBhY3Jvc3MgdGhlIHNlY3Rpb24uIEZvciB0aGlzIHJlYXNvbiBMb2dOb3JtYWxpc2UoKSBpcyBub3Qgc3VpdGFibGUgYW5kIFNldXJhdCByZWNjb21lbmQgcnRoZSB1c2Ugb2YgU0NUcmFuc2Zvcm0oKSBpbnN0ZWFkCmBgYHtyfQpicmFpbiA8LSBTQ1RyYW5zZm9ybShicmFpbiwgYXNzYXkgPSAiU3BhdGlhbCIsIHZlcmJvc2UgPSBGQUxTRSkKYGBgCgojIFZpc3VhbGlzYXRpb24KCkhpZ2hsaWdodCBwYXJ0aWN1bGFyIGZlYXR1cmVzCmBgYHtyfQpTcGF0aWFsRmVhdHVyZVBsb3QoYnJhaW4sIGZlYXR1cmVzID0gYygiSHBjYSIsICJUdHIiKSkKYGBgCgpgYGB7cn0KcDEgPC0gU3BhdGlhbEZlYXR1cmVQbG90KGJyYWluLCBmZWF0dXJlcyA9ICJUdHIiLCBwdC5zaXplLmZhY3RvciA9IDEpCnAyIDwtIFNwYXRpYWxGZWF0dXJlUGxvdChicmFpbiwgZmVhdHVyZXMgPSAiVHRyIiwgYWxwaGEgPSBjKDAuMSwgMSkpCnAxICsgcDIKYGBgCiMgRGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uLCBjbHVzdGVyaW5nLCBhbmQgdmlzdWFsaXphdGlvbgpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KYnJhaW4gPC0gUnVuUENBKGJyYWluLCBhc3NheSA9ICJTQ1QiLCB2ZXJib3NlID0gRkFMU0UpCmJyYWluIDwtIEZpbmROZWlnaGJvcnMoYnJhaW4sIHJlZHVjdGlvbiA9ICJwY2EiLCBkaW1zID0gMTozMCkKYnJhaW4gPC0gRmluZENsdXN0ZXJzKGJyYWluLCB2ZXJib3NlID0gRkFMU0UpCmJyYWluIDwtIFJ1blVNQVAoYnJhaW4sIHJlZHVjdGlvbiA9ICJwY2EiLCBkaW1zID0gMTozMCkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KcDEgPC0gRGltUGxvdChicmFpbiwgcmVkdWN0aW9uID0gInVtYXAiLCBsYWJlbCA9IFRSVUUpCnAyIDwtIFNwYXRpYWxEaW1QbG90KGJyYWluLCBsYWJlbCA9IFRSVUUsIGxhYmVsLnNpemUgPSAzKQpwMSArIHAyCmBgYAoKYGBge3J9ClNwYXRpYWxEaW1QbG90KGJyYWluLCBjZWxscy5oaWdobGlnaHQgPSBDZWxsc0J5SWRlbnRpdGllcyhvYmplY3QgPSBicmFpbiwgaWRlbnRzID0gYygyLCAxLCA0LCAzLAogICAgNSwgOCkpLCBmYWNldC5oaWdobGlnaHQgPSBUUlVFLCBuY29sID0gMykKYGBgCiMgSW50ZXJhY3RpdmUgcGxvdHMKYGBge3IsIGV2YWw9RkFMU0V9ClNwYXRpYWxEaW1QbG90KGJyYWluLCBpbnRlcmFjdGl2ZSA9IFRSVUUpIAoKU3BhdGlhbEZlYXR1cmVQbG90KGJyYWluLCBmZWF0dXJlcyA9ICJUdHIiLCBpbnRlcmFjdGl2ZSA9IFRSVUUpCmBgYAoKIyBJZGVudGlmaWNhdGlvbiBvZiBzcGF0aWFsbHkgdmFyaWFibGUgZmVhdHVyZXMKCjFzdCBtZXRob2QgOiBVc2luZyBwcmlvciBrbm93bGVkZ2UKCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQpkZV9tYXJrZXJzIDwtIEZpbmRNYXJrZXJzKGJyYWluLCBpZGVudC4xID0gNSwgaWRlbnQuMiA9IDYpClNwYXRpYWxGZWF0dXJlUGxvdChvYmplY3QgPSBicmFpbiwgZmVhdHVyZXMgPSByb3duYW1lcyhkZV9tYXJrZXJzKVsxOjNdLCBhbHBoYSA9IGMoMC4xLCAxKSwgbmNvbCA9IDMpCgpgYGAKCjJuZCBtZXRob2Q6IExvb2tpbmcgZm9yIHBhdHRlcm5zIGluIHRoZSBkYXRhCgpgYGB7cn0KYnJhaW4gPC0gRmluZFNwYXRpYWxseVZhcmlhYmxlRmVhdHVyZXMoYnJhaW4sIGFzc2F5ID0gIlNDVCIsIGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhicmFpbilbMTo1MDBdLAogICAgc2VsZWN0aW9uLm1ldGhvZCA9ICJtYXJrdmFyaW9ncmFtIikKdG9wLmZlYXR1cmVzIDwtIGhlYWQoU3BhdGlhbGx5VmFyaWFibGVGZWF0dXJlcyhicmFpbiwgc2VsZWN0aW9uLm1ldGhvZCA9ICJtYXJrdmFyaW9ncmFtIiksIDYpClNwYXRpYWxGZWF0dXJlUGxvdChicmFpbiwgZmVhdHVyZXMgPSB0b3AuZmVhdHVyZXMsIG5jb2wgPSAzLCBhbHBoYSA9IGMoMC4xLCAxKSkKYGBgCgpNb3JlIHR1dG9yaWFscyBvbiBkYXRhIGludGVncmF0aW9uLCBzdWJzZXR0aW5nIGFuZCBtdWx0aXBsZSBzbGljZSBkYXRhIGF2YWlsYWJsZSBhdCBodHRwczovL3NhdGlqYWxhYi5vcmcvc2V1cmF0L2FydGljbGVzL3NwYXRpYWxfdmlnbmV0dGUuaHRtbAoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgo=